package com.warpcode.gpsloggerlite;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Vector;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class ShowLocationsActivity extends Activity 
{        
	static final int REQUEST_ACCOUNT_PICKER = 1;
	static final int REQUEST_AUTHORIZATION = 2;
	static final int SAVE_TO_DRIVE = 3;
	static final int SAVE_TO_SD = 4;
	
	static final String PDF_LOCATION = "/GPS Logger/PDF";
	static final String PDF_EXTENSION = ".pdf";
	static final String PDF_MIME_TYPE = "application/pdf";
	
	static final String KML_TEXT = "KML format";
	static final String PDF_TEXT = "PDF format";

	private static Drive service;
	private GoogleAccountCredential credential;
	private String value;

	private LocationTrackerAdapter locta;
    private LocationDatabase db;
        
    ProgressDialog pDialog;
    Context context;
    AlertDialog alert;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_locations);
                
        db = new LocationDatabase(this);
                
        ListView list = (ListView) findViewById(R.id.coordinates);
        locta = new LocationTrackerAdapter(this, db.getLocations());
        list.setAdapter(locta);
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }
        
    public boolean onCreateOptionsMenu(Menu menu)
    {                                             
    	getMenuInflater().inflate(R.menu.show_locations, menu);
    	return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
    	switch (item.getItemId()) 
    	{
        	case android.R.id.home:
                this.setResult(RESULT_OK);
                finish();
                return true;
    	}
        return super.onOptionsItemSelected(item);
    }
        
        
    public void drive(MenuItem item)
    {
    	createPDFFile(SAVE_TO_DRIVE);
    }
        
    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) 
    {
    	switch (requestCode) 
    	{
        	case REQUEST_ACCOUNT_PICKER:
        		if (resultCode == RESULT_OK && data != null && data.getExtras() != null) 
        		{
        			String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
        			if (accountName != null) 
        			{
        				credential.setSelectedAccountName(accountName);
        				service = getDriveService(credential);
        				saveFileToDrive();
        			}
        		}
        		break;
        	case REQUEST_AUTHORIZATION:
        		if (resultCode == Activity.RESULT_OK) 
        		{
        			saveFileToDrive();
        		}
        		
        		else 
        		{
        			startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
        		}
        		break;
    	}
    }
        
    private void saveFileToDrive() 
    {
    	context = this;
    	Thread t = new Thread(new Runnable() 
    	{
    		@Override
            public void run() 
    		{
    			try 
    			{
                    File dir = new File(Environment.getExternalStorageDirectory() + PDF_LOCATION);
                    dir.mkdirs();        
                    File fileContent = new File(dir+"/"+ value + PDF_EXTENSION);
                    FileContent mediaContent = new FileContent(PDF_MIME_TYPE, fileContent);

                    com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType(PDF_MIME_TYPE);

                    runOnUiThread(new Runnable() 
                    {
                    	@Override
                    	public void run() 
                    	{
						pDialog = ProgressDialog.show(context, "Uploading To Drive", "Please wait as your file is being uploaded to Google Drive");	
                    	}
                    });
                  
                    com.google.api.services.drive.model.File file = service.files().insert(body, mediaContent).execute();
                    if (file != null) 
                    {
                    	runOnUiThread(new Runnable() 
                    	{
                    		@Override
                    		public void run() 
                    		{
							Toast.makeText(getApplicationContext(), "File Uploaded To Drive Successfully",Toast.LENGTH_SHORT).show();
							pDialog.dismiss();
                    		}
                    	}); 
                    	fileContent.delete();
                    }
                } 
    			catch (UserRecoverableAuthIOException e) 
    			{
    				startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                } 
    			catch (IOException e) 
    			{
    				e.printStackTrace();
                }
    		}
    	});
        t.start();
    }

    private Drive getDriveService(GoogleAccountCredential credential) 
    {
    	return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
            	.build();
    }
        
    public void onResume()
    {
    	super.onResume();
    	locta.changeCursor(db.getLocations());
    }

    public void showDetails(View view)
    {
    	TextView id = (TextView) view.findViewById(R.id.id);
    	Intent intent = new Intent(this,ShowDetailsActivity.class);
    	String loc[] = db.getLocationWithId(Integer.parseInt(id.getText().toString()));         
    	if(loc!=null)
    	{
    		intent.putExtra("id",id.getText().toString());
    		intent.putExtra("time",loc[0]);
    		intent.putExtra("latitude",loc[1]);
    		intent.putExtra("longitude",loc[2]);
    		intent.putExtra("altitude",loc[3]);
    		intent.putExtra("speed",loc[4]);
    		startActivity(intent);
    	}
    }
        
    public void saveAS(MenuItem item)
    {     
    	if(item.getTitle().equals(KML_TEXT))
    		createKMLFile();
                 
    	else if(item.getTitle().equals(PDF_TEXT))
    	{
    		createPDFFile(SAVE_TO_SD); 
    	}              
    }
                
    private void createKMLFile()
    {
    	final Context context = this;
    	final EditText input = new EditText(this);
    	AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
    		alertDialogBuilder.setView(input);
    		alertDialogBuilder.setTitle("Save Locations");
            alertDialogBuilder.setMessage("You are saving your Locations in KML Format.Please enter a name for your file:")
            	.setCancelable(false)
            	.setPositiveButton("Cancel",
            new DialogInterface.OnClickListener()
            {      
            		public void onClick(DialogInterface dialog, int id)
            		{
            			dialog.cancel();
            		}
            });
            
        alertDialogBuilder.setNegativeButton("Ok",
            new DialogInterface.OnClickListener()
        	{
            	public void onClick(DialogInterface dialog, int id)
            	{
            		dialog.dismiss();
            		
            		Thread t = new Thread(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							final String value = input.getText().toString().trim();
			                  
		            		if(value.equals(""))
		            		{
		                          Toast.makeText(getApplicationContext(), "Please enter a valid file name", Toast.LENGTH_LONG).show();      
		            		}
		            		else
		            		{
		         		      runOnUiThread(new Runnable() {
									
									@Override
									public void run() {
										// TODO Auto-generated method stub
										pDialog = ProgressDialog.show(context, "Generating KML", "Please wait as your KML is being generated");	
									}
								});
		            			KMLWriter store = new KMLWriter(context,value);   
		            			store.write();
		            			runOnUiThread(new Runnable() {
									
									@Override
									public void run() {
										// TODO Auto-generated method stub
										Toast.makeText(getApplicationContext(), "Successfully saved your locations in "+value+".kml", Toast.LENGTH_LONG).show();
										pDialog.dismiss();	
									}
								});		            			
		            		}
						}
					});
            		t.start();
            }
         });
         alert = alertDialogBuilder.create();
         alert.show();
    }
        
    private void createPDFFile(int n)
    {
    	final EditText input = new EditText(this);
    	context = this;
    	final int num = n;
    	AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setView(input);
        alertDialogBuilder.setTitle("Save Locations");
        alertDialogBuilder.setMessage("You are saving your Locations in PDF Format.Please enter a name for your file:")
        	.setCancelable(true)
        	.setPositiveButton("Cancel",
            new DialogInterface.OnClickListener()
        	{      
        		public void onClick(DialogInterface dialog, int id)
        		{
        			dialog.cancel();  
        		}
        	});
        alertDialogBuilder.setNegativeButton("Ok",
            new DialogInterface.OnClickListener()
        	{
            	public void onClick(DialogInterface dialog, int id)
            	{
            		alert.dismiss();
            		Thread t =new Thread(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							value = input.getText().toString().trim();
			                  
		            		if(value.equals(""))
		            		{
		            			Toast.makeText(getApplicationContext(), "Please enter a valid file name", Toast.LENGTH_LONG).show();      
		            		}
		            		
		            		else
		            		{
		            			try 
		            			{
		            				
		            				runOnUiThread(new Runnable() {
										
										@Override
										public void run() {
											// TODO Auto-generated method stub
											pDialog = ProgressDialog.show(context, "Generating PDF", "Please wait as your PDF is being generated");	
										}
									});
		            				File root = Environment.getExternalStorageDirectory();
		                            File dir = new File(root.getAbsolutePath() + PDF_LOCATION);
		                            dir.mkdirs();      
		                            if(root.canWrite()) 
		                            {
		                            	File gpxfile = new File(dir+"/"+ value + PDF_EXTENSION);
		                            	FileOutputStream out = new FileOutputStream(gpxfile);
		                            	Document doc = new Document();
		                                 
		                            	PdfWriter.getInstance(doc,out);
		                                doc.open();
		                                doc.addTitle(value+PDF_EXTENSION);
		                                Vector<String[]> matrix = db.getLocationsMatrix();
		                                 
		                                String row[];
		                                 
		                                PdfPTable table = new PdfPTable(6);
		                                 
		                                Paragraph str = new Paragraph("GPS log\n\n\n");
		                             
		                                str.setAlignment(1);
		                             
		                                doc.add(str);
		                              
		                                table.addCell("Sno");
		                                table.addCell("Time");
		                                table.addCell("Latitude");
		                                table.addCell("Longitude");
		                                table.addCell("Altitude");
		                                table.addCell("Speed");
		                                 
		                                for(int i=0;i<matrix.size();i++)
		                                {
		                                	table.addCell(""+(i+1));
		                                    row = matrix.get(i);
		                                    for(int j=0;j<5;j++)
		                                    table.addCell(row[j]);          
		                                }
		                                 
		                                doc.add(table);
		                                doc.close();
		                                
		                                runOnUiThread(new Runnable() {
											
											@Override
											public void run() {
												// TODO Auto-generated method stub
												pDialog.dismiss();
											}
										});
		                                 
		                                if(num == SAVE_TO_SD)
		                                	runOnUiThread(new Runnable() {
												
												@Override
												public void run() {
													// TODO Auto-generated method stub
													Toast.makeText(getApplicationContext(), "Successfully saved your locations in "+value+".pdf", Toast.LENGTH_LONG).show();
												}
											});

		                                	
		                                else if(num == SAVE_TO_DRIVE)
		                                {	 
		                                	credential = GoogleAccountCredential.usingOAuth2(context, DriveScopes.DRIVE);
		                                	startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
		                                }
		                            }
		                                     
		                            else
		                            	throw new IOException();        
		            			} 
		            			catch (IOException e) 
		            			{
		            				e.printStackTrace();
		                        } 
		            			catch (DocumentException e) 
		            			{
		            				e.printStackTrace();
		            			}
		            		}
						}
            		}	
            		);
            		t.start();
            	}
        	});
        alert = alertDialogBuilder.create();
        alert.show();
    }
        
        
    public void deleteAll(View view)
    {
    	AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
            
    	alertDialogBuilder.setTitle("Confirm Delete");
    	alertDialogBuilder.setMessage("Are you sure you want to delete the database?")
        	.setCancelable(false)
        	.setPositiveButton("No",
        	new DialogInterface.OnClickListener()
        	{        
        		public void onClick(DialogInterface dialog, int id)
        		{
        			dialog.cancel();
        		}
        	});
    	alertDialogBuilder.setNegativeButton("Yes",
            new DialogInterface.OnClickListener()
    		{
            	public void onClick(DialogInterface dialog, int id)
            	{
        	        db.deleteAll();
        	        locta.changeCursor(db.getLocations());
            	}  
    		});
            alertDialogBuilder.create().show();
    }    
}
